package com.example.sfm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sfm.exception.ObjectException;
import com.example.sfm.handler.TemplateStyleHandler;
import com.example.sfm.pojo.dto.TeachersDto;
import com.example.sfm.pojo.dto.TeachersImportDto;
import com.example.sfm.pojo.dto.TeachersQueryDto;
import com.example.sfm.pojo.entity.Teachers;
import com.example.sfm.mapper.TeachersMapper;
import com.example.sfm.pojo.entity.Users;
import com.example.sfm.pojo.vo.TeachersExportVo;
import com.example.sfm.pojo.vo.TeachersVo;
import com.example.sfm.result.PageResult;
import com.example.sfm.service.ITeachersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.sfm.service.IUsersService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author sfm
 * @since 2025-03-07
 */
@Service
@RequiredArgsConstructor
public class TeachersServiceImpl extends ServiceImpl<TeachersMapper, Teachers> implements ITeachersService {
    @Lazy
    private final IUsersService userService;

    @Override
    @Transactional
    public void createTeacher(TeachersDto dto) {
        // 校验用户存在性
        Users user = userService.getById(dto.getUserId());
        if (user == null) {
            throw new ObjectException("用户不存在");
        }

        // 校验教师编号唯一性
        if (lambdaQuery().eq(Teachers::getTeacherNumber, dto.getTeacherNumber()).exists()) {
            throw new ObjectException("教师编号已存在");
        }

        Teachers entity = BeanUtil.copyProperties(dto, Teachers.class);
        if (!save(entity)) {
            throw new ObjectException("创建失败");
        }
    }

    @Override
    public PageResult<TeachersVo> listTeachers(TeachersQueryDto dto) {
        LambdaQueryWrapper<Teachers> wrapper = new LambdaQueryWrapper<Teachers>()
                .like(StringUtils.isNotBlank(dto.getTeacherNumber()),
                        Teachers::getTeacherNumber, dto.getTeacherNumber())
                .eq(StringUtils.isNotBlank(dto.getDepartment()),
                        Teachers::getDepartment, dto.getDepartment())
                .eq(StringUtils.isNotBlank(dto.getTitle()),
                        Teachers::getTitle, dto.getTitle())
                .like(StringUtils.isNotBlank(dto.getResearchKeyword()),
                        Teachers::getResearchArea, dto.getResearchKeyword())
                .orderByDesc(Teachers::getCreatedAt);

        Page<Teachers> page = page(new Page<>(dto.getPageNum(), dto.getPageSize()), wrapper);

        return new PageResult<>(page.getTotal(),
                page.getRecords().stream()
                        .map(this::convertToVoWithUser)
                        .toList());
    }

    private TeachersVo convertToVoWithUser(Teachers entity) {
        TeachersVo vo = BeanUtil.copyProperties(entity, TeachersVo.class);
        // 关联查询用户信息
        Users user = userService.getById(entity.getUserId());
        if (user != null) {
            vo.setEmail(user.getEmail())
                    .setAvatar(user.getAvatar());
        }
        return vo;
    }

    @Override
    @Transactional
    public void updateTeacher(Integer id, TeachersDto dto) {
        Teachers entity = getById(id);
        if (entity == null) throw new ObjectException("教师不存在");

        // 校验教师编号修改
        if (!entity.getTeacherNumber().equals(dto.getTeacherNumber())) {
            if (lambdaQuery()
                    .eq(Teachers::getTeacherNumber, dto.getTeacherNumber())
                    .ne(Teachers::getId, id)
                    .exists()) {
                throw new ObjectException("教师编号已存在");
            }
        }

        BeanUtil.copyProperties(dto, entity);
        if (!updateById(entity)) {
            throw new ObjectException("更新失败");
        }
    }

    @Override
    @Transactional
    public void deleteTeachers(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new ObjectException("ID列表不能为空");
        }
        List<Integer> distinctIds = ids.stream().distinct().toList();
        if (!removeBatchByIds(distinctIds)) {
            throw new ObjectException("删除失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importTeachers(@NotNull MultipartFile file) {
        try {
            List<Teachers> teachers = EasyExcel.read(file.getInputStream())
                    .head(TeachersImportDto.class)
                    .sheet()
                    .doReadSync()
                    .stream()
                    .map(obj -> convertImportData((TeachersImportDto) obj))
                    .toList();

            System.out.println(teachers);
            if (!saveBatch(teachers)) {
                throw new ObjectException("批量导入失败");
            }
        } catch (IOException e) {
            throw new ObjectException("文件读取失败");
        }
    }

    private Teachers convertImportData(@NotNull TeachersImportDto dto) {
        System.out.println(dto);
        // 校验用户存在性
        if (!userService.exists(new LambdaQueryWrapper<Users>().eq(Users::getId, dto.getUserId()))) {
            throw new ObjectException("用户不存在: " + dto.getUserId());
        }

        // 校验教师编号唯一性
        if (lambdaQuery().eq(Teachers::getTeacherNumber, dto.getTeacherNumber()).exists()) {
            throw new ObjectException("教师编号已存在: " + dto.getTeacherNumber());
        }

        return BeanUtil.copyProperties(dto, Teachers.class);
    }

    @Override
    public void exportTeachers(@NotNull HttpServletResponse response, TeachersQueryDto dto) {
        try {
            List<TeachersExportVo> data = list().stream().map(teachers ->
                    BeanUtil.copyProperties(teachers, TeachersExportVo.class)
                            .setEmail(userService.getById(teachers.getUserId()).getEmail())).toList();

            if (data.isEmpty()) {
                throw new ObjectException("导出数据为空");
            }
            String fileName = URLEncoder.encode(String.valueOf(LocalDate.now()), StandardCharsets.UTF_8);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

            // 写入数据
            EasyExcel.write(response.getOutputStream(), TeachersExportVo.class)
                    .registerWriteHandler(new TemplateStyleHandler())
                    .sheet("教师信息")
                    .doWrite(data);

            // 手动刷新流
            response.getOutputStream().flush();
        } catch (IOException e) {
            throw new ObjectException("导出失败");
        }
    }
}
